package musicplayer

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime"
	"time"

	"github.com/faiface/beep"
	"github.com/faiface/beep/mp3"
	"github.com/faiface/beep/speaker"
)

type MusicEntry struct {
	Id         string   //编号
	Name       string   //歌名
	Artist     string   //作者
	Source     string   //位置
	Type       string   //类型
	Filestream *os.File // 文件流
}

func (men *MusicEntry) Open() {
	var err error
	men.Filestream, err = os.Open(men.Source)
	if err != nil {
		log.Fatal(err)
	}
}

func (men *MusicEntry) Play() {
	streamer, format, err := mp3.Decode(men.Filestream)
	if err != nil {
		log.Fatal(err)
	}
	defer streamer.Close()

	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	fmt.Println("music length :", streamer.Len())
	speaker.Play(streamer)
	select {}
}

// PlayerMusic 播放音频函数
func PlayerMusic(done chan bool, song string) {
	//fmt.Printf("播放: %s", song)
	switch runtime.GOOS {
	// 根据操作系统类型选择命令
	case "darwin": // Mac OS X
		_ = exec.Command("afplay", song).Run()
	case "linux": // Linux
		//winPlayerMusic(song)
		_ = exec.Command("mpg123", song).Run()
	case "windows": // Windows
		winPlayerMusic(song)
		// _ = exec.Command("cmd", "/c", "start", song).Run()
	default:
		fmt.Println("不支持的操作系统")
	}
	// 通知任务已完成
	done <- true
}

func winPlayerMusic(song string) {
	// 打开mp3文件
	audioFile, err := os.Open(song)
	if err != nil {
		log.Println("[ERROR]读取文件——>", err)
	}
	// 使用defer防止文件描述服忘记关闭导致资源泄露
	//goland:noinspection GoUnhandledErrorResult
	defer audioFile.Close()
	// 对文件进行解码
	audioStreamer, format, err := mp3.Decode(audioFile)
	if err != nil {
		log.Println("[ERROR]解码——>", err)
	}
	//goland:noinspection GoUnhandledErrorResult
	defer audioStreamer.Close()
	// 采样率
	_ = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	// 这里播放音乐
	done := make(chan struct{})
	speaker.Play(beep.Seq(audioStreamer, beep.Callback(func() {
		// 播放完成调用回调函数
		done <- struct{}{}
	})))
	//等待播放完成
	<-done
}
